#include "stdafx.h"
#include "TypeCNCU.h"
TypeCNCU::TypeCNCU():
GeneralNCU(TypeC)
{
}
TypeCNCU::TypeCNCU(const unsigned int &config):
GeneralNCU(TypeC,config), TypeANCU(config)
{
}
TypeCNCU::TypeCNCU(const unsigned int &config,
				   const vector<double> &paras):
GeneralNCU(TypeC,config), TypeANCU(config)
{
	parameters(paras);
}

TypeCNCU::TypeCNCU(const TypeCNCU &rhs):
GeneralNCU(rhs), TypeANCU(rhs), m_interVent(rhs.m_interVent)
{
}
TypeCNCU& TypeCNCU::operator=(const TypeCNCU &rhs)
{
	if ( this != &rhs)
	{
		TypeANCU::operator =(rhs);
		m_interVent = rhs.m_interVent;
	}
	return (*this);
}
TypeCNCU::~TypeCNCU()
{
}
/*********************************************
	Configuration Section
*********************************************/
// get the number of parameters of a NCU
const unsigned int TypeCNCU::number() const
{
	return ((2*nSequence())+ 2);
}
/*********************************************
	Parameters Section
*********************************************/
// assign all parametrs of a NCU
bool TypeCNCU::parameters(const vector<double> &paras)
{
	if ( paras.size() != number() )
	{
		errMsg = msg[2];
		return false;
	}
	else
	{
		vector<double>::const_iterator iter = paras.begin();
		initialSill(*iter);  // assign the value of the initial sill
		reset(); // set the value of the current sill to the value of the initial sill
		++ iter;
		m_interVent.VentCoe(*iter); // assign the value of the single lateral output
		++ iter;
		vector<double> tmp(iter, paras.end());
		sequence(tmp); // assign the values of the sequence of the lateral output
		return true;
	}
}
// get all parameters of a NCU
vector<double> TypeCNCU::parameters() const
{
	vector<double> paras, tmp;
	paras.push_back(TypeANCU::initialSill());
	paras.push_back(
		m_interVent.VentCoe()
		);
	tmp = TypeANCU::sequence().parameters();
	paras.insert(paras.end(), tmp.begin(), tmp.end());
	return paras;
}
// virtual constructor
GeneralNCU* TypeCNCU::clone() const
{
	return new TypeCNCU(*this);
}
// simulation
outputPair TypeCNCU::simulation(const double &input)
{
	update(input);
	outputPair flow;
	flow.first = TypeANCU::output(currentSill());
	flow.second = bottom(currentSill());
	currentSill(
		currentSill() - flow.first-flow.second
		);
	return flow;
}
// get the genome information
vector<const GenomeType*> TypeCNCU::genome() const
{
	vector<const GenomeType*> tmp = TypeANCU::genome();
	// insert the intermediate single vent into the genome set
	vector<const GenomeType*>::iterator loc = tmp.begin();
	++loc;
	tmp.insert( loc, &genomeSet().GetVentGenome() ); 
	return tmp;
}
double TypeCNCU::bottom(const double &sill)
{
	return m_interVent.output(sill);
}